﻿using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Editing.Attributes;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;

namespace CCTool.Scripts.FeaturePross
{
    /// <summary>
    /// Interaction logic for FeatureAttribute.xaml
    /// </summary>
    public partial class FeatureAttribute : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        public FeatureAttribute()
        {
            InitializeComponent();
            // 更新页面
            UpdataAtt();
            // 订阅地图选择更改事件
            MapSelectionChangedEvent.Subscribe(OnMapSelectionChanged);
        }


        private void OnMapSelectionChanged(MapSelectionChangedEventArgs args)
        {
            UpdataAtt();
        }


        // 更新页面
        private async void UpdataAtt()
        {
            try
            {
                // 清空tb_message
                tb_message.Document.Blocks.Clear();

                await QueuedTask.Run(() =>
                {

                    // 获取要素的Geometry类型
                    var geometryTypeDict = GetGeometryType();

                    if (geometryTypeDict.Count == 0)
                    {
                        return;
                    }

                    // 要处理的Geometry类型
                    GeometryType geoType = geometryTypeDict.First().Key;

                    // 标题栏更新
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        title.Content = geometryTypeDict.First().Value;
                    });


                    // 获取活动地图视图中选定的要素集合
                    var selectedSet = MapView.Active.Map.GetSelection();

                    // 将选定的要素集合转换为字典形式
                    var selectedList = selectedSet.ToDictionary();
                    // 创建一个新的 Inspector 对象以检索要素属性
                    var inspector = new Inspector();

                    // 遍历每个选定图层及其关联的对象 ID
                    foreach (var layer in selectedList)
                    {
                        // 获取图层和关联的对象 ID
                        FeatureLayer mapMember = layer.Key as FeatureLayer;
                        List<long> oids = layer.Value;
                        // 使用当前图层的第一个对象 ID 加载 Inspector
                        inspector.Load(mapMember, oids[0]);
                        // 获取选定要素的几何类型
                        var geometryType = inspector.Shape.GeometryType;

                        // 获取图层名
                        string layerName = mapMember.Name;
                        // 获取图层的坐标系
                        var sr = mapMember.GetSpatialReference();


                        // 检查几何类型，不符号就跳过
                        if (geometryType != geoType)
                        {
                            continue;
                        }

                        AddMessage($"图层：【{layerName}】\r", Brushes.Blue);
                        AddMessage($"坐标系：{sr.Name}\r");

                        // 遍历当前图层中的每个对象 ID
                        foreach (var oid in oids)
                        {
                            AddMessage($"【要素ID：{oid}】\r", Brushes.Green);

                            // 使用当前对象 ID 加载 Inspector
                            inspector.Load(mapMember, oid);

                            // 面要素
                            if (geometryType == GeometryType.Polygon)
                            {
                                GetPolygonAtt(mapMember, inspector, oid);
                            }
                            // 线要素
                            else if (geometryType == GeometryType.Polyline)
                            {
                                GetPolylineAtt(mapMember, inspector, oid);
                            }
                            // 点要素
                            else if (geometryType == GeometryType.Point)
                            {
                                GetPointAtt(mapMember, inspector, oid);
                            }
                        }
                    }

                });

                // 显示结果

            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }

        }


        // 获取要处理的要素Geometry类型
        private Dictionary<GeometryType, string> GetGeometryType()
        {

            Dictionary<GeometryType, string> result = new Dictionary<GeometryType, string>();
            // 是否包含点线面
            bool hasPolygon = false;
            bool hasPolyline = false;
            bool hasPoint = false;

            // 获取活动地图视图中选定的要素集合
            var selectedSet = MapView.Active.Map.GetSelection();

            // 将选定的要素集合转换为字典形式
            var selectedList = selectedSet.ToDictionary();
            // 创建一个新的 Inspector 对象以检索要素属性
            var inspector = new Inspector();

            // 遍历每个选定图层及其关联的对象 ID
            foreach (var layer in selectedList)
            {
                // 获取图层和关联的对象 ID
                MapMember mapMember = layer.Key;
                List<long> oids = layer.Value;
                // 使用当前图层的第一个对象 ID 加载 Inspector
                inspector.Load(mapMember, oids[0]);
                // 获取选定要素的几何类型
                var geometryType = inspector.Shape.GeometryType;

                // 检查几何类型
                if (geometryType == GeometryType.Polygon)
                {
                    hasPolygon = true;
                }
                if (geometryType == GeometryType.Polyline)
                {
                    hasPolyline = true;
                }
                if (geometryType == GeometryType.Point)
                {
                    hasPoint = true;
                }
            }

            // 输出结果
            if (hasPolygon && hasPolyline && hasPoint) { result.Add(GeometryType.Polygon, "选择内容包含点、线、面，只显示面要素属性"); }
            if (hasPolygon && !hasPolyline && !hasPoint) { result.Add(GeometryType.Polygon, "选择内容为面要素"); }
            if (hasPolygon && hasPolyline && !hasPoint) { result.Add(GeometryType.Polygon, "选择内容包含点、面，只显示面要素属性"); }
            if (hasPolygon && !hasPolyline && hasPoint) { result.Add(GeometryType.Polygon, "选择内容包含线、面，只显示面要素属性"); }

            if (!hasPolygon && hasPolyline && hasPoint) { result.Add(GeometryType.Polyline, "选择内容包含点、线，只显示线要素属性"); }
            if (!hasPolygon && hasPolyline && !hasPoint) { result.Add(GeometryType.Polyline, "选择内容为线面要素"); }
            if (!hasPolygon && !hasPolyline && hasPoint) { result.Add(GeometryType.Point, "选择内容为点面要素"); }

            return result;
        }



        private void GetPolygonAtt(MapMember mapMember, Inspector inspector, long oid)
        {
            // 使用当前对象 ID 加载 Inspector
            inspector.Load(mapMember, oid);
            // 将要素转换为多边形
            Polygon polygon = inspector.Shape as Polygon;

            // 面积
            AddMessage($"面积：{polygon.Area}\r");

            // 部件数
            var partCount = polygon.Parts.Count;
            // polygon的外环数
            int exteriorCount = polygon.ExteriorRingCount;

            AddMessage($"部件数：{exteriorCount}\r");
            // 内环数
            int interiorCount = partCount - exteriorCount;
            if (interiorCount != 0)
            {
                AddMessage($"内环数：{interiorCount} \r");
            }

            // 界址点数
            var pointCount = polygon.PointCount;
            AddMessage($"界址点数：{pointCount - partCount} \r");

            string overlap = CheckTool.CheckPolygonOverlap(polygon);
            if (overlap != "")
            {
                AddMessage($"{overlap} \r");
            }
        }


        private void GetPolylineAtt(MapMember mapMember, Inspector inspector, long oid)
        {
            // 使用当前对象 ID 加载 Inspector
            inspector.Load(mapMember, oid);
            // 将要素转换为多边形
            Polyline polyline = inspector.Shape as Polyline;

            // 长度
            AddMessage($"长度：{polyline.Length}\r");

            // 部件数
            var partCount = polyline.Parts.Count;
            AddMessage($"部件数：{partCount+1}\r");

            // 闭合的部件数
            int closedCount = CheckTool.CheckPolylineClosed(polyline);
            AddMessage($"闭合的线部件数：{closedCount} \r");
            AddMessage($"未闭合的线部件数：{partCount -closedCount} \r");

            // 界址点数
            var pointCount = polyline.PointCount;
            AddMessage($"界址点数：{pointCount - partCount} \r");

            
        }

        private void GetPointAtt(MapMember mapMember, Inspector inspector, long oid)
        {
            // 使用当前对象 ID 加载 Inspector
            inspector.Load(mapMember, oid);
            // 将要素转换为多边形
            MapPoint mp = inspector.Shape as MapPoint;

            int digit = 3;

            double xx = Math.Round(mp.X, digit);
            double yy = Math.Round(mp.Y, digit);

            // 坐标
            AddMessage($"X坐标：{xx}\r");
            AddMessage($"Y坐标：{yy}\r");

        }

        // 添加信息框文字
        private void AddMessage(string add_text, SolidColorBrush solidColorBrush = null)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                solidColorBrush ??= Brushes.Black;
                // 创建一个新的TextRange对象，范围为新添加的文字
                TextRange newRange = new TextRange(tb_message.Document.ContentEnd, tb_message.Document.ContentEnd)
                {
                    Text = add_text
                };
                // 设置新添加文字的颜色
                newRange.ApplyPropertyValue(TextElement.ForegroundProperty, solidColorBrush);
                // 设置新添加文字的样式
                newRange.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);

                //tb_message.Focus();        // RichTextBox获取焦点，有时也可以不用
                tb_message.ScrollToEnd();        // RichTextBox滚动到光标位置
            });
        }

        private void btn_help_Click(object sender, RoutedEventArgs e)
        {
            string url = "https://blog.csdn.net/xcc34452366/article/details/152045588";
            UITool.Link2Web(url);
        }

    }
}
